﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockCommon.baseclass;
using Utilities;
using StockCommon.data;
using StockCommon;
using StockImport.dataimport.common;
using System.Threading;

namespace StockImport.dataimport.tse.sb
{
    public abstract class SB_Fetcher_Common : DBAccess
    {
        protected abstract TwnStockMarketType getTargetMarket();
        protected abstract String getStoreFileName(String code, DateTime date);
        protected abstract bool CrawlingSB(string code, DateTime date, int tc);

        int _repeatTime = 15;
        public int RepeatTime
        {
            get { return _repeatTime; }
            set { _repeatTime = value; }
        }
        
        
        public static void createTask(List<String> toCreate, DateTime date, TwnStockMarketType t)
        {
            String market = EnumUtils.GetStringValue(t);
            //因為有id ..所以 OK~
            List<SBDataTask> tasks = new List<SBDataTask>();
            foreach (String code in toCreate)
            {
                SBDataTask task = new SBDataTask();
                task.日期 = date;
                task.StockCode = code;
                task.state = 1;
                task.SBId = NewGuid.create("sbtk");
                task.lastprocessTime = DateTime.Now;
                task.market = market;
                tasks.Add(task);
            }
            if (tasks.Count > 0)
            {
                getContext().SBDataTasks.InsertAllOnSubmit(tasks);
                getContext().SubmitChanges();
            }

        }
        protected void CheckTaskToCreate(DateTime date, TwnStockMarketType market)
        {
            //是否已經有tag.-->可以加一個task
            HashSet<String> codes = StockDailyIndexServices.getLastValidCodes(date, market);
            String sql = String.Format("select SBDataTask.StockCode from SBDataTask where SBDataTask.日期 ='{0}'", DateUtils.toShortDateFormat(date));
            List<String> ll = getContext().ExecuteQuery<String>(sql).ToList<String>();
            if (codes.Count == ll.Count)
                return;
            List<String> toCreate = null;
            if (ll.Count == 0)
            {
                toCreate = new List<String>(codes);
            }
            else
            {
                toCreate = new List<String>();
                HashSet<String> created = new HashSet<String>(ll);
                foreach (String code in codes)
                {
                    if (created.Contains(code))
                        continue;
                    toCreate.Add(code);
                }
            }
            if (toCreate.Count > 0)
                createTask(toCreate, date, getTargetMarket());
        }
        public void Update_On_Date(DateTime date)
        {
            CheckTaskToCreate(date, getTargetMarket());
            //開始抓取..
            int times = 0;
            while (true)
            {
                int c = performFetch(date);
                if (c == 0)
                    break;
                times++;
                if (times > RepeatTime)
                    break;
            }
        }
        public void Update()
        {
            //check 狀態...每一筆資料的.......
            DateTime date = StockDailySellBuyServices.getMaxSBDate(getTargetMarket());
            Update_On_Date(date);            
        }

        protected void resetUnfinished(List<SBDataTask> tasks)
        {
            foreach (SBDataTask t in tasks)
            {
                if (SBTaskState.待處理.Equals((SBTaskState)t.state))
                    continue;
                if (SBTaskState.完成.Equals((SBTaskState)t.state))
                    continue;
                if (SBTaskState.已抓取.Equals((SBTaskState)t.state))
                    continue;
                if (SBTaskState.無資料.Equals((SBTaskState)t.state))
                    continue;
                t.state = 1;
            }

        }

        protected List<SBDataTask> getTaskOfDate(DateTime date, TwnStockMarketType market)
        {
            StockDataClassesDataContext context = getContext();
            var tasks = (from t in context.SBDataTasks where t.日期 == date select t);
            HashSet<String> codes = StockDailyIndexServices.getLastValidCodes(date, getTargetMarket());
            List<SBDataTask> result = new List<SBDataTask>();

            foreach (SBDataTask t in tasks)
            {
                if (codes.Contains(t.StockCode))
                    result.Add(t);
            }
            return result;
        }

        protected int performFetch(DateTime date)
        {
            List<SBDataTask> tasks = getTaskOfDate(date, getTargetMarket());
            //把每一個..有問題的都先修改
            resetUnfinished(tasks);
            //把沒有完成的修改成 SBTaskState.待處理
            int succ = 0;
            foreach (SBDataTask t in tasks)
            {
                bool changed = false;
                if (SBTaskState.待處理.Equals((SBTaskState)t.state))
                {
                    String code = t.StockCode;
                    t.state = (int)SBTaskState.抓取中;
                    int tc = StockDailyIndexServices.getTradeCount(code, date);
                    if (tc < 0)
                        tc = StockDailyIndexServices.getMaxTradeCount(code, 10);
                    if (tc < 0)
                        continue; //代表最近十天都沒有成交..這是一個錯誤!
                    if (tc == 0)
                    {
                        t.state = (int)SBTaskState.無資料;
                    }
                    else
                    {
                        changed = true;
                        if (CrawlingSB(code, date, tc))
                        {
                            t.state = (int)SBTaskState.已抓取;
                            System.Diagnostics.Debug.WriteLine("抓取:" + code);
                            succ++;
                        }
                        else
                        {
                            t.state = (int)SBTaskState.抓取錯誤;
                            System.Diagnostics.Debug.WriteLine("錯誤:" + code);
                            Thread.Sleep(2000);
                        }
                    }
                }
                if (changed)
                {
                    getContext().SubmitChanges();
                    changed = false;
                }
                if (succ > 5)
                {
                    succ = 0;
                    Thread.Sleep(2000);
                }
            }
            int unfinishcount = 0;
            int noData = 0;
            foreach (SBDataTask t in tasks)
            {
                if (SBTaskState.已抓取.Equals((SBTaskState)t.state))
                    continue;
                if (SBTaskState.完成.Equals((SBTaskState)t.state))
                    continue;
                if (SBTaskState.無資料.Equals((SBTaskState)t.state))
                {
                    noData++;
                    continue;
                }
                unfinishcount++;
            }
            return unfinishcount;
        }

    }
}
